package com.goertek.easyface.device;

import com.alibaba.fastjson2.JSON;
import com.goertek.easyface.entity.AAcsFaceDeviceConfig;
import com.goertek.easyface.entity.GateRecord;
import com.goertek.easyface.entity.GateRecordVO;
import com.goertek.easyface.entity.WSMessage;
import com.goertek.easyface.service.AcsDataService;
import com.goertek.easyface.websocket.WebSocketServer;
import com.netsdk.common.Res;
import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.ToolKits;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;

/**
 * @program: easy-face
 * @description: 智能事件回调
 * @author: devin.duj
 * @create: 2024-03-28 11:26
 */
@Slf4j
public class AnalyzerDataHander implements NetSDKLib.fAnalyzerDataCallBack{
    private SimpleDateFormat formatMonth = new SimpleDateFormat("yyyy-MM");
    private SimpleDateFormat formatDay = new SimpleDateFormat("yyyy-MM-dd");
    private SimpleDateFormat formatTime = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    private AAcsFaceDeviceConfig deviceInfo;
    private String imageDir;  //图片存储文件夹
    private AcsDataService acsDataService;   //查询BPM流程记录
    public AnalyzerDataHander(AAcsFaceDeviceConfig deviceInfo, String imageDir, AcsDataService acsDataService){
        this.deviceInfo = deviceInfo;
        this.imageDir = imageDir;
        this.acsDataService = acsDataService;
    }

    public int invoke(NetSDKLib.LLong lAnalyzerHandle, int dwAlarmType,
                      Pointer pAlarmInfo, Pointer pBuffer, int dwBufSize,
                      Pointer dwUser, int nSequence, Pointer reserved)
    {
        if (lAnalyzerHandle.longValue() == 0 || pAlarmInfo == null) {
            return -1;
        }
        Date date = new Date();
        File path = new File(imageDir + "/" + formatMonth.format(date) + "/" + formatDay.format(date));
        if (!path.exists()) {
            path.mkdirs();
        }

        ///< 门禁事件
        if(dwAlarmType == NetSDKLib.EVENT_IVS_ACCESS_CTL) {
            NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO msg = new NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO();
            ToolKits.GetPointerData(pAlarmInfo, msg);

            // 保存图片，获取图片缓存
            String empNo = new String(msg.szUserID).trim();  //工号
            String snapPicPath = path.getAbsolutePath() + "\\" + deviceInfo.getId() + "_" + empNo + "_" + System.currentTimeMillis() + ".jpg";  // 保存图片地址
            byte[] buffer = pBuffer.getByteArray(0, dwBufSize);
            ByteArrayInputStream byteArrInputGlobal = new ByteArrayInputStream(buffer);

            try {
                BufferedImage gateBufferedImage = ImageIO.read(byteArrInputGlobal);
                if(gateBufferedImage != null) {
                    ImageIO.write(gateBufferedImage, "jpg", new File(snapPicPath));
                }
                // 图片以及门禁信息界面显示
                processEvent(msg,Base64.getEncoder().encodeToString(buffer),snapPicPath);
            } catch (Exception e2) {
                log.error("接收门禁异常", e2);
            }

        }
        return 0;
    }

    //处理事件数据
    public void processEvent(NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO msg,String imageBase64Code,String filePath) {
        GateRecord gateRecord = new GateRecord();
        gateRecord.setDeviceId(deviceInfo.getId());
        // 时间
        if(!(msg.UTC == null || msg.UTC.toString().isEmpty())) {
            msg.UTC.setTime(msg.UTC.dwYear, msg.UTC.dwMonth, msg.UTC.dwDay, msg.UTC.dwHour+8, msg.UTC.dwMinute, msg.UTC.dwSecond);
            try {
                gateRecord.setEventTime(formatTime.parse(msg.UTC.toString()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        if(msg.emEventType == 1) {
            gateRecord.setEventType("进门");
        } else if(msg.emEventType == 2){
            gateRecord.setEventType("出门");
        }
        // 开门状态
        if(msg.bStatus == 1) {
            gateRecord.setEventStatus("成功");
        } else {
            gateRecord.setEventStatus("失败");
        }
        // 开门方式
        gateRecord.setEventMode(Res.string().getOpenMethods(msg.emOpenMethod));
        // 卡名
        try {
            gateRecord.setEmpName(new String(msg.szCardName, "GBK").trim());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 卡号
        gateRecord.setCardNo( new String(msg.szCardNo).trim());
        // 用户ID(工号)
        gateRecord.setEmpNo(new String(msg.szUserID).trim());
        //图片路径
        gateRecord.setImagePath(filePath);

        log.info(deviceInfo.getDeviceName() + " 刷脸记录 - " + gateRecord.toString());

        //人脸机验证成功后
        if(StringUtils.isNotEmpty(gateRecord.getEmpNo())){
            //从数据库查询人员携带物品等信息
            GateRecordVO gateRecordVO =  acsDataService.queryAcsDataByEmpNo(gateRecord,imageBase64Code,deviceInfo);
            //推送到websocket
            if(gateRecordVO == null){
                if(StringUtils.isNotEmpty(deviceInfo.getWebsocketAddress())){
                    WSMessage wsMessage = new WSMessage();
                    wsMessage.setType(WSMessage.TYPE_FACE);
                    wsMessage.setHasPermission(false);
                    wsMessage.setMessage("未查询到符合条件的BPM流程记录");
                    gateRecordVO = new GateRecordVO();
                    gateRecordVO.setEventDeviceName(deviceInfo.getDeviceName());  //刷脸设备
                    gateRecordVO.setEventDoorName(deviceInfo.getDoorName());
                    gateRecordVO.setWorkNo(gateRecord.getEmpNo());  //工号
                    gateRecordVO.setImageBase64Code(imageBase64Code);
                    wsMessage.setResult(gateRecordVO);
                    WebSocketServer.broadCastInfo(JSON.toJSONString(wsMessage),deviceInfo.getWebsocketAddress());
                }
            }else{
                WSMessage wsMessage = new WSMessage();
                wsMessage.setType(WSMessage.TYPE_FACE);
                wsMessage.setHasPermission(true);
                wsMessage.setMessage("验证成功");
                wsMessage.setResult(gateRecordVO);
                WebSocketServer.broadCastInfo(JSON.toJSONString(wsMessage),deviceInfo.getWebsocketAddress());
            }
        }

    }
}